using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Frogger_Input;

// ****************************************************************************** //
//   This component handles the playing and loading of all game sounds & music    //
// ****************************************************************************** //

// ****************************************************************************** //
//   NOTE: to avoid lots of problems in sharing sound data between components and //
//   to avoid being obliged to create/dispose the sound component every time we   //
//   change screen or context, we have decided to keep the sound component as     //
//      the first component being created by the game (see Game1.cs), so that we  //
//    always know what is the component (Game.Components[0]) that has not to be   //
//                        disposed till the end of the game.                      //
// ****************************************************************************** //

namespace Frogger_Game
{
    //sound structure to be used in all other components
    public class SoundData
    {
        public SoundEffect HopSound;
        public SoundEffectInstance HopSoundInstance;
        public SoundEffect CrashSound;
        public SoundEffectInstance CrashSoundInstance;
        public SoundEffect TimeSound;
        public SoundEffectInstance TimeSoundInstance;
        public SoundEffect SplashSound;
        public SoundEffectInstance SplashSoundInstance;
        public SoundEffect StartSound;
        public SoundEffectInstance StartSoundInstance;
        public SoundEffect FilledHoleSound;
        public SoundEffectInstance FilledHoleSoundInstance;
        public SoundEffect Theme;
        public SoundEffectInstance ThemeInstance;
        public SoundEffect WinSound;
        public SoundEffectInstance WinSoundInstance;
        public SoundEffect GameOverSound;
        public SoundEffectInstance GameOverSoundInstance;

        public void PlaySound(SoundEffectInstance sound)
        {
            if (!sound.IsDisposed && sound.State == SoundState.Paused)
            {
                sound.Stop();
            }
            sound.Play();
        }

        public void PauseSound(SoundEffectInstance sound)
        {
            if (!sound.IsDisposed && sound.State == SoundState.Playing)
            {
                sound.Pause();
            }
        }

        public void StopSound(SoundEffectInstance sound)
        {
            if (!sound.IsDisposed && sound.State == SoundState.Playing)
            {
                sound.Stop();
            }
        }

           public void PauseAllEffects()
        {
               PauseSound(CrashSoundInstance); 
               PauseSound(FilledHoleSoundInstance); 
               PauseSound(HopSoundInstance); 
               PauseSound(TimeSoundInstance); 
               PauseSound(SplashSoundInstance);
               PauseSound(StartSoundInstance);
               PauseSound(WinSoundInstance);
               PauseSound(GameOverSoundInstance);
        }

        public void SetEffectsVolume(int volume)
        {
            if (volume > 10)
            {
                CrashSoundInstance.Volume = 1.0f;
                FilledHoleSoundInstance.Volume = 1.0f;
                HopSoundInstance.Volume = 1.0f;
                TimeSoundInstance.Volume = 1.0f;
                SplashSoundInstance.Volume = 1.0f;
                StartSoundInstance.Volume = 1.0f;
                WinSoundInstance.Volume = 1.0f;
                GameOverSoundInstance.Volume = 1.0f;
            }
            else if (volume < 0)
            {
                CrashSoundInstance.Volume = 0;
                FilledHoleSoundInstance.Volume = 0;
                HopSoundInstance.Volume = 0;
                TimeSoundInstance.Volume = 0;
                SplashSoundInstance.Volume = 0;
                StartSoundInstance.Volume = 0;
                GameOverSoundInstance.Volume = 0;
            }
            else
            {
                CrashSoundInstance.Volume = volume * 0.1f;
                FilledHoleSoundInstance.Volume = volume * 0.1f;
                HopSoundInstance.Volume = volume * 0.1f;
                TimeSoundInstance.Volume = volume * 0.1f;
                SplashSoundInstance.Volume = volume * 0.1f;
                StartSoundInstance.Volume = volume * 0.1f;
                WinSoundInstance.Volume = volume * 0.1f;
                GameOverSoundInstance.Volume = volume * 0.1f;
            }
            
        }


        public void EffectsVolumeUp(int volume)
        {
            if (volume < 10)
            {
                CrashSoundInstance.Volume = volume * 0.1f;
                FilledHoleSoundInstance.Volume = volume * 0.1f;
                HopSoundInstance.Volume = volume * 0.1f;
                TimeSoundInstance.Volume = volume * 0.1f;
                SplashSoundInstance.Volume = volume * 0.1f;
                StartSoundInstance.Volume = volume * 0.1f;
                WinSoundInstance.Volume = volume * 0.1f;
                GameOverSoundInstance.Volume = volume * 0.1f;
            }
            else
            {
                CrashSoundInstance.Volume = 1.0f;
                FilledHoleSoundInstance.Volume = 1.0f;
                HopSoundInstance.Volume = 1.0f;
                TimeSoundInstance.Volume = 1.0f;
                SplashSoundInstance.Volume = 1.0f;
                StartSoundInstance.Volume = 1.0f;
                WinSoundInstance.Volume = 1.0f;
                GameOverSoundInstance.Volume = 1.0f;
            }
        }

        public void EffectsVolumeDown(int volume)
        {
            if (volume > 0)
            {
                CrashSoundInstance.Volume = volume * 0.1f;
                FilledHoleSoundInstance.Volume = volume * 0.1f;
                HopSoundInstance.Volume = volume * 0.1f;
                TimeSoundInstance.Volume = volume * 0.1f;
                SplashSoundInstance.Volume = volume * 0.1f;
                StartSoundInstance.Volume = volume * 0.1f;
                WinSoundInstance.Volume = volume * 0.1f;
                GameOverSoundInstance.Volume = volume * 0.1f;
            }
            else
            {
                CrashSoundInstance.Volume = 0;
                FilledHoleSoundInstance.Volume = 0;
                HopSoundInstance.Volume = 0;
                TimeSoundInstance.Volume = 0;
                SplashSoundInstance.Volume = 0;
                StartSoundInstance.Volume = 0;
                WinSoundInstance.Volume = 0;
                GameOverSoundInstance.Volume = 0;
            }
        }

        public void SetMusicVolume(int volume)
        {
            if (volume > 10)
            {
                ThemeInstance.Volume = 1.0f;
            }
            else if (volume < 0)
            {
                ThemeInstance.Volume = 0.0f;
            }
            else
            {
                ThemeInstance.Volume = volume * 0.1f;
            }

        }


        public void MusicVolumeUp(int volume)
        {
            if (volume < 10)
            {
                ThemeInstance.Volume = volume * 0.1f;
            }
            else
            {
                ThemeInstance.Volume = 1.0f;
            }
        }

        public void MusicVolumeDown(int volume)
        {
            if (volume > 0)
            {
                ThemeInstance.Volume = volume * 0.1f;
            }
            else
            {
                ThemeInstance.Volume = 0.0f;
            }
        }
    }
    /// <summary>
    /// Component that implements IUpdateable.
    /// </summary>
    public class Sound : Microsoft.Xna.Framework.DrawableGameComponent
    {
        SoundData snd = new SoundData();

        public Sound(Game game)
            : base(game)
        {
            Game.Services.AddService(typeof(SoundData),snd);
        }


        public override void Initialize()
        {

            base.Initialize();
        }

        /// <summary>
        /// Load sound files
        /// </summary>
        protected override void LoadContent()
        {
            snd.HopSound = Game.Content.Load<SoundEffect>("Audio/hop");
            snd.HopSoundInstance = snd.HopSound.CreateInstance();
            snd.CrashSound = Game.Content.Load<SoundEffect>("Audio/crash");
            snd.CrashSoundInstance = snd.CrashSound.CreateInstance();
            snd.TimeSound = Game.Content.Load<SoundEffect>("Audio/time_finishing");
            snd.TimeSoundInstance = snd.TimeSound.CreateInstance();
            snd.TimeSoundInstance.IsLooped = true;
            snd.SplashSound = Game.Content.Load<SoundEffect>("Audio/splash");
            snd.SplashSoundInstance = snd.SplashSound.CreateInstance();
            snd.StartSound = Game.Content.Load<SoundEffect>("Audio/start");
            snd.StartSoundInstance = snd.StartSound.CreateInstance();
            snd.FilledHoleSound = Game.Content.Load<SoundEffect>("Audio/croak");
            snd.FilledHoleSoundInstance = snd.FilledHoleSound.CreateInstance();
            snd.Theme = Game.Content.Load<SoundEffect>("Audio/theme");
            snd.ThemeInstance = snd.Theme.CreateInstance();
            snd.ThemeInstance.IsLooped = true;
            snd.WinSound = Game.Content.Load<SoundEffect>("Audio/win");
            snd.WinSoundInstance = snd.WinSound.CreateInstance();
            snd.GameOverSound = Game.Content.Load<SoundEffect>("Audio/game_over");
            snd.GameOverSoundInstance = snd.GameOverSound.CreateInstance();
        }


        /// <summary>
        /// Update method
        /// </summary>
        public override void Update(GameTime gameTime)
        {
            if (Game1.isPaused == false)
            {

                if (Frogger_Input.InputHandler.GetState().down || Frogger_Input.InputHandler.GetState().up || Frogger_Input.InputHandler.GetState().left || Frogger_Input.InputHandler.GetState().right)
                {
                    if (snd.HopSoundInstance.State == SoundState.Playing)
                    {
                        snd.HopSoundInstance.Stop();
                    }
                    snd.HopSoundInstance.Play();
                }

                if (CarsSimulation.collision_detected == true)
                {
                    snd.HopSoundInstance.Stop();
                    snd.CrashSoundInstance.Play();
                }

                if (RiverSimulation.splash_trigger == true)
                {
                    snd.HopSoundInstance.Stop();
                    snd.SplashSoundInstance.Play();
                }


                if (WinLogic.time_finished == false && GameState.game_state.time_counter > WinLogic.time_limit - WinLogic.time_limit / 4)
                {
                    snd.TimeSoundInstance.Play();
                }
                else
                {
                    if (snd.TimeSoundInstance.State == SoundState.Playing)
                        snd.TimeSoundInstance.Stop();
                }

                if (WinLogic.time_finished == true)
                {
                    snd.CrashSoundInstance.Play();
                }

                if (FrogSimulation.win_trigger == 1)
                {
                    snd.HopSoundInstance.Stop();
                    snd.FilledHoleSoundInstance.Play();
                }
                
                if (FrogSimulation.win_trigger == 2)
                {
                    snd.HopSoundInstance.Stop();
                    snd.CrashSoundInstance.Play();
                }
                base.Update(gameTime);

            }
        }

        /// <summary>
        /// Method to dispose active services
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(SoundData));
            base.Dispose(disposing);
        }
    }
}
